import {PdfProcessor} from "./utils/pdfProcessor.js";
import {jqueryUtils} from './utils/jqueryUtils.js';

const Path = require("path");

$("#btnAddCol").click(function () {
    addCol();
});

function addCol() {
    var colNum = $("#table01 .files-th").length;
    $(`<th class="files-th">文件名${colNum + 1}</th>`).insertAfter($("#table01 tr.title .files-th:last"));

    $("#table01 tr.files-tr").each(function () {
        $(`<td class="files-td" path=""></td>`).insertAfter($(this).children(".files-td:last"));
    });
}

$("#btnDeleteCol").click(function () {
    deleteCol();
});

function deleteCol() {
    var colNum = $("#table01 .files-th").length;
    if (colNum > 1) {
        $("#table01 tr.title>.files-th:last").remove();
        $("#table01 tr.files-tr").each(function () {
            $(this).children(".files-td:last").remove();
        });
    }
}

$("#btnClear").click(function () {
    clearTable();
});

function clearTable() {
    $("table:not(.hide) td.files-td").each(function () {
        $(this).empty();
    });
}

function resetTable() {
    $("#table01 tr.title>.files-th:gt(0)").remove();
    $("#table01 tr.files-tr .files-td:gt(0)").remove();
    $("table:not(.hide) tr.files-tr:gt(0)").remove();
    clearTable();
}

$("#btnReset").click(function () {
    resetTable();
});

const ExportOption = jqueryUtils.generateEnum(["source", "custom"]);
const FileNameOption = jqueryUtils.generateEnum(["yes", "no"]);
const MergeOption = jqueryUtils.generateEnum(["horizontal", "vertical", "insertPages", "replacePages", "deletePages"]);

$("#btnMerge").click(async function () {
    let exportOption = getExportOption();
    let mergeOption = getMergeOption();
    let fileNameOption = getFileNameOption();
    let success = true;

    if ($("#table01:not(.hide)").length > 0) {
        // table01

        //region 将路径存放到二维数组
        let paths2D = [];
        switch (mergeOption) {
            case MergeOption.horizontal:
            default:
                var i = 0;
                $("#table01 .files-tr").each(function () {
                    paths2D[i] = [];
                    let j = 0;
                    $(this).children(".files-td").each(function () {
                        paths2D[i][j] = $(this).attr('path').toString();
                        j++;
                    });
                    i++;
                });
                break;
            case MergeOption.vertical:
                var j = 0;
                $("#table01 .files-th").each(function () {
                    paths2D[j] = [];
                    j++;
                });
                var i = 0;
                $("#table01 .files-tr").each(function () {
                    j = 0;
                    $(this).children(".files-td").each(function () {
                        paths2D[j][i] = $(this).attr('path').toString();
                        j++;
                    });
                    i++;
                });
                break;
        }
        //endregion

        for (let k = 0; k < paths2D.length; k++) {
            let pathTarget = getPathTarget(paths2D[k][0], exportOption, fileNameOption);
            if (!jqueryUtils.checkStringArrayNullOrEmpty(paths2D[k])) {
                await PdfProcessor.mergeFiles(paths2D[k], pathTarget);
            } else {
                success = false;
            }
        }
    } else if ($("#table02:not(.hide)").length > 0) {
        $("table:not(.hide) tr.files-tr").each(function () {
            let pathInserter = $(this).children(".inserter").attr("path");
            let pathInsertee = $(this).children(".insertee").attr("path");
            let startNum = parseInt($(this).find(":text.pageNum").attr("value")) - 1;
            let pathTarget = getPathTarget(pathInsertee, exportOption, fileNameOption);
            switch (mergeOption) {
                case MergeOption.insertPages:
                    PdfProcessor.insertFile(pathInserter, pathInsertee, [], startNum, pathTarget);
                    break;
                case MergeOption.replacePages:
                    PdfProcessor.replaceFile(pathInserter, pathInsertee, [], startNum, pathTarget);
                    break;
            }

        });

    } else if ($("#table03:not(.hide)").length > 0) {
        $("table:not(.hide) tr.files-tr").each(function () {
            let pathSource = $(this).children(".files-td").attr("path");
            let pageNumsStr = $(this).find(":text.pageNums").attr("value");
            // let pageNums = convertStringToNumRange(pageNumsStr);
            let pathTarget = getPathTarget(pathSource, exportOption, fileNameOption);
            PdfProcessor.deletePages(pathSource, pageNumsStr, pathTarget);
        });
    }

    //region UI变化
    resetTable();
    if (success) {
        setTimeout(() => {
            $("#success").removeClass("hide");
        }, 500);
    }
    //endregion
});

/**
 * 将字符串转换成正整数数组
 * @param str {string} 待转换的字符串
 * @returns {number[]}
 */
function convertStringToNumRange(str) {
    let subStrs = str.split(",");
    let numRange = [];
    let i = 0;
    for (const subStr of subStrs) {
        if (subStr !== "") {
            if (patternHiphen.test(subStr)) {
                let ends = subStr.split('-');
                let start = parseInt(ends[0]) - 1;
                let end = parseInt(ends[1]) - 1;
                for (let j = start; j <= end; j++) {
                    numRange[i] = j;
                    i++;
                }
            } else if (patternInteger.test(subStr)) {
                numRange[i] = parseInt(subStr) - 1;
                i++;
            }
        }
    }
    return numRange;
}

/**
 * 获取目标文件保存路径
 * @param pathSrc {string} 源文件路径
 * @param exportOption {ExportOption} 输出模式
 * @param fileNameOption {FileNameOption} 是否给文件名添加前缀
 * @returns {string}
 */
function getPathTarget(pathSrc, exportOption, fileNameOption = FileNameOption.yes) {
    let pathTarget = "";
    let prefix = "";
    switch (fileNameOption) {
        case FileNameOption.yes:
        default:
            prefix = "【已处理】";
            break;
        case FileNameOption.no:
            break;
    }
    switch (exportOption) {
        case ExportOption.source:
            pathTarget = Path.join(Path.dirname(pathSrc), prefix + Path.basename(pathSrc));
            break;
        case ExportOption.custom:
            pathTarget = Path.join(pathTarget_Global, prefix + Path.basename(pathSrc));
            break;
    }
    return pathTarget;
}

function getExportOption() {
    let option;
    switch ($("[name=exportOption]:checked").attr("value")) {
        case "source":
            option = ExportOption.source;
            break;
        case "default":
            option = ExportOption.default;
            break;
        case "custom":
            option = ExportOption.custom;
            break;
        default:
            option = ExportOption.source;
            break;
    }
    return option;
}

function getFileNameOption() {
    let option;
    switch ($("[name=changeFileName]:checked").attr("value")) {
        case "yes":
        default:
            option = FileNameOption.yes;
            break;
        case "no":
            option = FileNameOption.no;
            break;
    }
    return option;
}

function getMergeOption() {
    let option;
    switch ($("[name=mergeOption]:checked").attr("value")) {
        case "horizontal":
        default:
            option = MergeOption.horizontal;
            break;
        case "vertical":
            option = MergeOption.vertical;
            break;
        case "insertPages":
            option = MergeOption.insertPages;
            break;
        case "replacePages":
            option = MergeOption.replacePages;
            break;
        case "deletePages":
            option = MergeOption.deletePages;
            break;
    }
    return option;
}

function addListenerToTd() {
    let files_tds = $("table:not(.hide) .files-td");
    files_tds.each(function () {
        if (!jqueryUtils.isBindJq($(this), "drop")) {
            $(this).bind("drop", (e) => {
                e.preventDefault();
                e.stopPropagation();
                let files = e.originalEvent.dataTransfer.files;
                let index_tr = $(this).parent().index("table:not(.hide) .files-tr");
                let index_td = $(this).index(`table:not(.hide) .files-tr:eq(${index_tr}) .files-td`);
                let trs = $(`table:not(.hide) .files-tr`);
                let emptyRowNum = 0;
                let emptyTds = [];
                let iTds = 0;
                trs.each(function () {
                    emptyTds[iTds] = $(this).children(`table:not(.hide) .files-td:eq(${index_td}):empty`);
                    emptyRowNum += emptyTds[iTds].length;
                    iTds++;
                });
                let num = 0;
                for (const file of files) {
                    if (file.type == "application/pdf") {
                        num++;
                    }
                }
                // 添加空行
                if (emptyRowNum < num) {
                    appendTrs(num - emptyRowNum);
                }

                emptyTds = getEmptyTdsInSameCol(index_td);

                // 处理文件类型错乱的情况
                let i = 0;
                let wrongFileNames = "";
                for (const file of files) {
                    if (file.type == "application/pdf") {
                        emptyTds[i].attr("path", file.path);
                        emptyTds[i].text(file.name);
                        i++;
                    } else {
                        wrongFileNames += file.name + '、';
                    }
                }
                wrongFileNames = wrongFileNames.substring(0, wrongFileNames.length - 1);
                if (num < files.length) {
                    $("#info").text(wrongFileNames);
                    $("#warn").removeClass("hide");
                }
            });
        }

        if (!jqueryUtils.isBindJq($(this), "dragover")) {
            $(this).bind("dragover", (e) => {
                e.preventDefault(); // 取消默认
                e.stopPropagation(); // 阻止冒泡
            });
        }

        // 右键单击唤出contextmenu
        if (!jqueryUtils.isBindJq($(this), "contextmenu")) {
            $(this).bind("contextmenu", (e) => {
                let coords = [];
                coords[0] = $(this).parent("tr").index("table:not(.hide) tr.files-tr");
                coords[1] = $(this).index(`table:not(.hide) tr.files-tr:eq(${coords[0]}) td.files-td`);
                ipcRenderer.send("context-menu0", coords);
            })
        }
    });

    // 删除行
    let delBtns = $("table:not(.hide) .delete-row-btn");
    delBtns.each(function () {
        if (!jqueryUtils.isBindJq($(this), "click")) {
            $(this).click(function () {
                if ($("table:not(.hide) .files-tr").length > 1) {
                    $(this).parents(".files-tr").remove();
                    // 重置序号
                    let i = 1;
                    $("table:not(.hide) td.index").each(function () {
                        $(this).text(i);
                        i++;
                    });
                }
            });
        }
    });

    // 校验页码输入是否合法
    $("table:not(.hide) :text.pageNum").each(function () {
        if (!jqueryUtils.isBindJq($(this), "input")) {
            $(this).bind("input propertychange", function () {
                let num = $(this).val();
                if (!patternInteger.test(num)) {
                    $(this).siblings("span.alert").removeClass("hide");
                } else {
                    $(this).siblings("span.alert").addClass("hide");
                }
            });
        }
    });

    // 校验页码输入是否合法（多页）
    $("table:not(.hide) :text.pageNums").each(function () {
        if (!jqueryUtils.isBindJq($(this), "input")) {
            $(this).bind("input propertychange", function () {
                let num = $(this).val();
                if (!patternPages.test(num)) {
                    $(this).siblings("span.alert").removeClass("hide");
                } else {
                    $(this).siblings("span.alert").addClass("hide");
                }
            });
        }
    });

    // 双击表头排序（按文件名升序排列）
    let ths = $("table:not(.hide) .files-th");
    ths.each(function () {
        if (!jqueryUtils.isBindJq($(this), "click")) {
            $(this).dblclick(function () {
                let index_th = $(this).index(`table:not(.hide) .files-th`);
                let tds = getTdsInSameCol(index_th);
                for (let i = 0; i < tds.length; i++) {
                    for (let j = i + 1; j < tds.length; j++) {
                        if (tds[i].text() === "" && tds[j].text() !== "") {
                            swap(tds[i], tds[j]);
                        } else if (tds[i].text() !== "" && tds[j].text() !== "" && tds[j].text() < tds[i].text()) {
                            swap(tds[i], tds[j]);
                        }
                    }
                }
            });
        }
    });

    let pageNum_tds = $("table:not(.hide) td.pageNum");
    pageNum_tds.each(function () {
            if (!jqueryUtils.isBindJq($(this), "contextmenu")) {
                $(this).bind("contextmenu", (e) => {
                    let coords = [];
                    coords[0] = $(this).parent("tr").index("table:not(.hide) tr.files-tr");
                    coords[1] = $(this).index(`table:not(.hide) tr.files-tr:eq(${coords[0]}) td.pageNum`);
                    ipcRenderer.send("pageNum0", coords);
                });
            }
        }
    );
}

function swap(td0, td1) {
    let tempText = td0.text();
    let tempPath = td0.attr("path");
    td0.text(td1.text());
    td0.attr("path", td1.attr("path"));
    td1.text(tempText);
    td1.attr("path", tempPath);
}

function getEmptyTdsInSameCol(indexCol) {
    let iTds = 0;
    let emptyTds = [];
    let trs = $(`table:not(.hide) .files-tr`);
    trs.each(function () {
        let temp = $(this).children(`.files-td:eq(${indexCol}):empty`);
        if (temp.length > 0) {
            emptyTds[iTds] = temp;
            iTds++;
        }
    });
    return emptyTds;
}

function getTdsInSameCol(indexCol) {
    let iTds = 0;
    let emptyTds = [];
    let trs = $(`table:not(.hide) .files-tr`);
    trs.each(function () {
        let temp = $(this).children(`.files-td:eq(${indexCol})`);
        if (temp.length > 0) {
            emptyTds[iTds] = temp;
            iTds++;
        }
    });
    return emptyTds;
}

$("body").on("dragover mousedown", (e) => {
    addListenerToTd();
    $("#warn").addClass("hide");
    $("#success").addClass("hide");
});

function appendTrs(rowNum) {
    if ($("#table01:not(.hide)").length > 0) {
        let colFilesNum = $("table:not(.hide) .files-th").length;
        for (let i = 0; i < rowNum; i++) {
            let rNum = $("table:not(.hide) .files-tr").length;
            $("table:not(.hide)").append("<tr class=\"files-tr\"></tr>");
            $("table:not(.hide) tr:last").append(`<td class="index">${rNum + 1}</td>`);
            for (let j = 0; j < colFilesNum; j++) {
                $("table:not(.hide) tr:last").append(`<td class="files-td" path=""></td>`);
            }
            $("table:not(.hide) tr:last").append(`
            <td class="delete-row-td">
            <button class="delete-row-btn">删除行</button>
            </td>
        `);
        }
    } else if ($("#table02:not(.hide)").length > 0) {
        for (let i = 0; i < rowNum; i++) {
            let rNum = $("table:not(.hide) .files-tr").length;
            $("table:not(.hide)").append("<tr class=\"files-tr\"></tr>");
            let $trLast = $("table:not(.hide) tr:last");
            $trLast.append(`<td class="index">${rNum + 1}</td>`);
            $trLast.append(`
                <td class="files-td inserter" path=""></td>
                <td class="files-td insertee" path=""></td>
                <td class="pageNum">
                    <input type="text" class="pageNum" value="1">
                    <span class="alert hide">不合法</span>
                </td>
                <td class="delete-row-td">
                    <button class="delete-row-btn">删除行</button>
                </td>
            `);
        }
    } else if ($("#table03:not(.hide)").length > 0) {
        let pageNum = $("#table03:not(.hide) :text.pageNums").last().attr("value");
        for (let i = 0; i < rowNum; i++) {
            let rNum = $("table:not(.hide) .files-tr").length;
            $("table:not(.hide)").append("<tr class=\"files-tr\"></tr>");
            let $trLast = $("table:not(.hide) tr:last");
            $trLast.append(`<td class="index">${rNum + 1}</td>`);
            $trLast.append(`
                <td class="files-td" path=""></td>
                <td class="pageNum">
                    <input type="text" class="pageNums" value="${pageNum}">
                    <span class="alert hide">不合法</span>
                </td>
                <td class="delete-row-td">
                    <button class="delete-row-btn">删除行</button>
                </td>
            `);
        }
    }
}

$(".fixBtn").click(function () {
    $("#warn").addClass("hide");
    $("#success").addClass("hide");
});

const {ipcRenderer, shell} = require("electron");
ipcRenderer.on("selectDirectory1", function (e, path) {
    if (path !== undefined) {
        pathTarget_Global = path;
        $("span.outputPath").text(path);
        $("#output").removeClass("hide");
    } else if ($("#output.hide").length === 1) {
        $(":radio[name=exportOption][value!=custom]").attr("checked", true);
        $(":radio[name=changeFileName][value=yes]").prop("checked", true);
    }
})

ipcRenderer.on("context-menu1", function (e, coords) {
    console.log("2");
    if (coords !== undefined) {
        $(`table:not(.hide) tr.files-tr:eq(${coords[0]}) td.files-td:eq(${coords[1]})`).empty();
    }
});

ipcRenderer.on("pageNum1", function (e, coords) {
    if (coords !== undefined) {
        let pageNumStr = $(`table:not(.hide) tr.files-tr:eq(${coords[0]}) td.pageNum:eq(${coords[1]}) :text`).attr("value");
        $(`table:not(.hide) td.pageNum :text`).each(function () {
            $(this).attr("value", pageNumStr);
        });
    }
});

let pathTarget_Global = "";
$(":radio[name=exportOption][value=custom]").click(function () {
    if ($(this).is(':checked')) {
        ipcRenderer.send('selectDirectory');
    }
});


$(":radio[name=exportOption][value!=custom]").click(function () {
    if ($(this).is(':checked')) {
        $("span.outputPath").empty();
        $("#output").addClass("hide");
        $(":radio[name=changeFileName][value=yes]").prop("checked", true);
    }
});

$(":radio[name=changeFileName][value=no]").click(function () {
    if ($(this).is(':checked') && $("#output.hide").length !== 0) {
        $(":radio[name=exportOption][value=custom]").prop("checked", true);
        ipcRenderer.send('selectDirectory');
    }
});

$(":radio[name=mergeOption][value=insertPages],[value=replacePages]").click(function () {
    if ($(this).is(':checked')) {
        $("#table01,#table03").addClass("hide");
        $("#table02").removeClass("hide");
        $("#btnAddCol").prop("disabled", true);
        $("#btnDeleteCol").prop("disabled", true);
    }
});

$(":radio[name=mergeOption][value=deletePages]").click(function () {
    if ($(this).is(':checked')) {
        $("#table01,#table02").addClass("hide");
        $("#table03").removeClass("hide");
        $("#btnAddCol").prop("disabled", true);
        $("#btnDeleteCol").prop("disabled", true);
    }
});

$(":radio[name='mergeOption'][value='vertical'],[value='horizontal']").click(function () {
    if ($(this).is(':checked')) {
        $("#table02,#table03").addClass("hide");
        $("#table01").removeClass("hide");
        $("#btnAddCol").prop("disabled", false);
        $("#btnDeleteCol").prop("disabled", false);
    }
});

// 单击打开输出文件夹
$("span.outputPath").click(function () {
    shell.openPath($(this).text());
});

const patternInteger = /^[1-9]{1}[0-9]*$/;
const patternPages = /^([1-9]{1}[0-9]*[,-]?)+[0-9]*$/;
const patternHiphen = /-/;